package it.infodea.tapestrydea.components;

import it.infodea.tapestrydea.support.annotations.AllowedExtensions;

import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.RenderSupport;
import org.apache.tapestry5.annotations.AfterRender;
import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary;
import org.apache.tapestry5.annotations.OnEvent;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Persist;
import org.apache.tapestry5.dom.Element;
import org.apache.tapestry5.ioc.AnnotationProvider;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.FormSupport;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.upload.components.Upload;

@IncludeJavaScriptLibrary( { "AjaxFileUpload.js", "Simulator.js" })
public class AjaxFileUpload extends Upload {

	private static final String EXTENSION_PARAM_NAME = "AjaxFileUploadExtensionParam";

	private static final String CHECK_EXTENSION_EVENT = "checkExtension";

	@Parameter
	private String onCompleteCallback;

	@Parameter
	private AnnotationProvider annotationProvider;

	@Parameter
	private String[] allowed = {};

	@Persist
	private String[] allowedList;

	private String uploadFieldDivId;

	@Inject
	private FormSupport formSupport;

	@Inject
	private ComponentResources resources;

	@Inject
	private RenderSupport support;

	@Inject
	private Request request;

	protected void beginRender(MarkupWriter writer) {
		if (resources.isBound("annotationProvider") && annotationProvider != null) {
			AllowedExtensions annotation = annotationProvider.getAnnotation(AllowedExtensions.class);
			if (annotation != null) {
				allowed = annotation.value();
			}
		}
		allowedList = allowed;
		uploadFieldDivId = getClientId() + "div";
		writer.element("div", "id", uploadFieldDivId);
		super.beginRender(writer);
		Element element = writer.getElement();
		element.attribute("onchange", "AjaxFileUploadUtil.checkExtension(this,'" + getEventUrl() + "', true);");
	}

	@AfterRender
	public void afterRender(MarkupWriter writer) {
		writer.end();
		super.afterRender(writer);
		String options = "{}";
		String formId = formSupport.getClientId();
		if (resources.isBound("onCompleteCallback") && onCompleteCallback != null) {
			options = "{onComplete:" + onCompleteCallback + "}";
		}
		support.addScript("$('%1$s').observe('submit', function(evt){" + "new AjaxFileUpload(null).submit($('%1$s'), %2$s);});", formId,
				options);
		support.addScript("$('%1$s').enable();", formId);
	}

	@OnEvent(CHECK_EXTENSION_EVENT)
	JSONObject checkExtension(String errorMessage) {
		String extension = request.getParameter(EXTENSION_PARAM_NAME);
		boolean isAllowed = isAllowed(extension.toLowerCase());
		resources.triggerEvent("validateExtension", new Object[] { extension }, null);
		return new JSONObject(String.format("{success:%s,errorMessage:'%s'}", isAllowed, errorMessage));
	}

	private boolean isAllowed(String extension) {
		for (String item : allowedList) {
			if (extension.equalsIgnoreCase(item) || AllowedExtensions.ALL.equalsIgnoreCase(item)) {
				return true;
			}
		}
		return false;
	}

	private String getEventUrl() {
		String errorMessage = resources.getMessages().get("extension-not-allowed");
		return resources.createEventLink(CHECK_EXTENSION_EVENT, errorMessage).toRedirectURI();
	}

}
